package Advance.Comunications;

import java.util.ArrayList;

/*
 * Description:生产消费者模型，用消费面包的程序来演示
 * Author: AMark
 * Date:11/12/2023
 * Time:11:12 PM
 */
//被消费的类，面包
class Bread {
    int id;
    Bread(int id) {
        this.id = id;
    }
}
//生产者和消费者共存在的场所：类似于商店
class GoodStack {
    int index = 0;
    Bread[] breads = new Bread[3];
    public synchronized void push(Bread bd) {
        while (index == breads.length) {   //判断数组是否是满的
            try {
                this.wait();  //如果数组是满的，让线程处于等待状态，当一个对象被唤醒之后不能立刻执行，所以这里使用的是while循环
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.notify();  //唤醒等待中的线程
        breads[index] = bd;
        index++;
        System.out.println("生产者：" + Thread.currentThread().getName() + "生产了新面包" + "当前面包数：" + this.index);
    }
    public synchronized Bread pop() {
        while (index == 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.notify();
        index--;
        System.out.printf("消费者" + Thread.currentThread().getName() + "消费了面包" + "当前面包数为：" + this.index);
        return breads[index];
    }
}
class Producer implements Runnable {
    GoodStack goodStack = null;
    Producer(GoodStack goodStack) {
        this.goodStack = goodStack;
    }
    //实现接口方法
    public void run() {
        for (int i = 0; i < 6; i++) {
            Bread bread = new Bread(i);
            goodStack.push(bread);
            try {
                Thread.sleep((int)(Math.random())*200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Consumer implements Runnable {
    GoodStack goodStack = null;
    Consumer(GoodStack goodStack) {
        this.goodStack = goodStack;
    }
    public void run() {
        for (int i = 0; i < 12; i++) {
            Bread bread = goodStack.pop();
            try {
                Thread.sleep((int)(Math.random())*200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class PCModel {
    public static void main(String[] args) {
        GoodStack goodStack = new GoodStack();
        Producer producer = new Producer(goodStack);
        Consumer consumer = new Consumer(goodStack);
        new Thread(producer).start();
        new Thread(producer).start();
        new Thread(consumer).start();
    }

}
